#include <Core/Core.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "tree-sitter/lib/include/tree_sitter/api.h"

#define USE_CURSOR 0

using namespace Upp;
extern "C" {
    TSLanguage *tree_sitter_c();
}

struct FunctionInfo: Moveable<FunctionInfo> {
    String function_name;
    int lineno_start;
    int lineno_end;
    Vector<String> parameters;

    FunctionInfo():lineno_start(0),lineno_end(0) {}

    ~FunctionInfo() 
    {
    }

};

Vector<FunctionInfo> extract_functions(String fpath) 
{
    Vector<FunctionInfo> function_lists;
    if (!FileExists(fpath)) 
    {
        return function_lists;
    }
    TSParser *parser = ts_parser_new();
    ts_parser_set_language(parser, tree_sitter_c());

    // 读取源文件
    FileIn in(fpath);
    if(!in.IsOpen() || !in.IsOK())
    {
        return function_lists;
    }
    String sIn = in.GetAll(in.GetStreamSize());
    in.Close();

    TSTree *tree = ts_parser_parse_string(parser, NULL, sIn, sIn.GetLength());
    TSNode root_node = ts_tree_root_node(tree);


#if USE_CURSOR
    // 创建树游标进行遍历
    TSTreeCursor cursor = ts_tree_cursor_new(root_node);
    ts_tree_cursor_reset(&cursor, root_node);
    ts_tree_cursor_goto_first_child(&cursor);

    do 
    {
        TSNode node = ts_tree_cursor_current_node(&cursor);
        const char *node_type = ts_node_type(node);

        if (strcmp(node_type, "function_definition") == 0) {
            FunctionInfo &info = function_lists.Add();

            // 获取函数起始行号
            TSPoint start_point = ts_node_start_point(node);
            info.lineno_start = start_point.row + 1;
            // 获取函数结束行号
            TSPoint end_point = ts_node_end_point(node);
            info.lineno_end = end_point.row + 1;

            // 提取函数声明器
            TSNode declarator = ts_node_child_by_field_name(node, "declarator", 10);
            if (ts_node_is_null(declarator)) continue;

            // 提取函数名称
            TSNode func_name_node = ts_node_child_by_field_name(declarator, "declarator", 10);
            if (ts_node_is_null(func_name_node)) continue;

            uint32_t start = ts_node_start_byte(func_name_node);
            uint32_t end = ts_node_end_byte(func_name_node);
            info.function_name = sIn.Mid(start, end-start); 

            // 提取参数列表
            TSNode params_node = ts_node_child_by_field_name(declarator, "parameters", 10);
            if (!ts_node_is_null(params_node)) 
            {
                uint32_t param_count = ts_node_child_count(params_node);
                // info.parameters = malloc(sizeof(char *) * param_count);
                // info.param_count = 0;

                for (uint32_t i = 0; i < param_count; i++) 
                {
                    TSNode param = ts_node_child(params_node, i);
                    if (strcmp(ts_node_type(param), "parameter_declaration") != 0) continue;

                    start = ts_node_start_byte(param);
                    end = ts_node_end_byte(param);
                    // info.parameters[info.param_count++] = strndup(source_code + start, end - start);
                    info.parameters.Add(sIn.Mid(start, end-start));
                }
            }
        }
    } while (ts_tree_cursor_goto_next_sibling(&cursor));

    ts_tree_cursor_delete(&cursor);
    ts_tree_delete(tree);
    ts_parser_delete(parser);
#else

    // 定义查询模式（注意空格敏感）
    const char *query_pattern = 
        "(function_definition"
        "  declarator: (function_declarator"
        "    declarator: (identifier) @func_name"
        "    parameters: (parameter_list) @params"
        "  )"
        ") @func";
    uint32_t error_offset;
    TSQueryError error_type;
    TSQuery *query = ts_query_new(
        tree_sitter_c(),
        query_pattern,
        strlen(query_pattern),
        &error_offset,
        &error_type
    );

    if (!query) {
        // fprintf(stderr, "Query error at offset %d: %d\n", error_offset, error_type);
        LOG("Query error at offset" << error_offset << ":" << (int)error_type);
        return function_lists;
    }

    TSQueryCursor *cursor = ts_query_cursor_new();
    ts_query_cursor_exec(cursor, query, root_node);

    TSQueryMatch match;
    uint32_t len;
    while (ts_query_cursor_next_match(cursor, &match)) {
        FunctionInfo &info = function_lists.Add();
        TSNode params_node, func_node, name_node;

        for (uint32_t i = 0; i < match.capture_count; i++) {
            TSQueryCapture capture = match.captures[i];
            const char *name = ts_query_capture_name_for_id(query, capture.index, &len);
            
            if (strcmp(name, "func") == 0) {
                func_node = capture.node;
                TSPoint start = ts_node_start_point(func_node);
                info.lineno_start = start.row + 1;
                TSPoint end = ts_node_end_point(func_node);
                info.lineno_end = end.row + 1;
            }
            else if (strcmp(name, "func_name") == 0) {
                name_node = capture.node;
                uint32_t start = ts_node_start_byte(name_node);
                uint32_t end = ts_node_end_byte(name_node);
                info.function_name = sIn.Mid(start, end-start); //strndup(source_code + start, end - start);
            }
            else if (strcmp(name, "params") == 0) {
                params_node = capture.node;
            }
        }

        // 处理参数列表
        if (!ts_node_is_null(params_node)) {
            // 参数列表的查询
            const char *param_query_pattern = "(parameter_declaration) @param";
            TSQuery *param_query = ts_query_new(
                tree_sitter_c(),
                param_query_pattern,
                strlen(param_query_pattern),
                &error_offset,
                &error_type
            );

            TSQueryCursor *param_cursor = ts_query_cursor_new();
            ts_query_cursor_exec(param_cursor, param_query, params_node);

            // info.parameters = malloc(sizeof(char*) * 16); // 预分配
            // info.param_count = 0;

            TSQueryMatch param_match;
            while (ts_query_cursor_next_match(param_cursor, &param_match)) {
                for (uint32_t i = 0; i < param_match.capture_count; i++) {
                    TSNode param_node = param_match.captures[i].node;
                    uint32_t start = ts_node_start_byte(param_node);
                    uint32_t end = ts_node_end_byte(param_node);
                    
                    // if (info.param_count >= 16) {
                    //     info.parameters = realloc(info.parameters, sizeof(char*) * (info.param_count + 1));
                    // }
                    // info.parameters[info.param_count++] = strndup(source_code + start, end - start);
                    info.parameters.Add(sIn.Mid(start, end-start));
                }
            }

            ts_query_cursor_delete(param_cursor);
            ts_query_delete(param_query);
        }

        // 添加到数组
        // functions = realloc(functions, sizeof(FunctionInfo) * (count + 1));
        // functions[count++] = info;
    }

    // 清理资源
    ts_query_cursor_delete(cursor);
    ts_query_delete(query);
    ts_tree_delete(tree);
    ts_parser_delete(parser);
#endif

    return function_lists;
}

CONSOLE_APP_MAIN
{
	const Vector<String>& cmd_line = CommandLine();
	if (cmd_line.GetCount() > 0 && FileExists(cmd_line[0]))
    {
        Vector<FunctionInfo> function_lists = extract_functions(cmd_line[0]);
        DUMP(function_lists.GetCount());
        for (auto &info : function_lists)
        {
            DUMP(info.function_name);
            DUMP(info.lineno_start);
            DUMP(info.lineno_end);
            for (auto &param : info.parameters)	
            {
                DUMP(param);	
            }
        }
    }
}
